package com.cn.yunhe.rentcars.security;

import java.util.List;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.cn.yunhe.rentcars.mapper.permission.AccountMapper;
import com.cn.yunhe.rentcars.mapper.permission.ResourceMapper;
import com.cn.yunhe.rentcars.model.permission.Account;
import com.cn.yunhe.rentcars.model.permission.Resource;

/**
 * 
 * SHIRO登录认证和角色权限认证
 * 
 * @author ZSL
 */
public class ShiroRealmImpl extends AuthorizingRealm {

    /**
     * 日志
     */
    private static Logger logger = LoggerFactory.getLogger(ShiroRealmImpl.class);

	/**
	 * 用户数据处理对象
	 */
    @Autowired
	private AccountMapper accountMapper;
    
    
	/**
	 * 权限处理对象
	 */
	@Autowired
	private ResourceMapper resourceMapper;

    /**
     * 登录认证
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
    	 //UsernamePasswordToken对象用来存放提交的登录信息
        UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;
        logger.info("验证当前Subject时获取到token为：" + ReflectionToStringBuilder.toString(token, ToStringStyle.MULTI_LINE_STYLE)); 
        //查出是否有此用户
       // User user=userMapper.getUserByName(usernamePasswordToken.getUsername());
        Account account = accountMapper.getAccountByName(usernamePasswordToken.getUsername());
        if(account!=null){
            // 若存在，将此用户存放到登录认证info中，无需自己做密码对比，SHIRO会为我们进行密码对比校验
            return new SimpleAuthenticationInfo(account.getUserName(), account.getUserpwd(), getName());
        }
        return null;
    }


    /**
     * 权限认证，为当前登录的Subject授予角色和权限 
     * @see 本例中该方法的调用时机为需授权资源被访问时 
     * @see 并且每次访问需授权资源时都会执行该方法中的逻辑，这表明本例中默认并未启用AuthorizationCache 
     * @see 如果连续访问同一个URL（比如刷新），该方法不会被重复调用，Shiro有一个时间间隔（也就是cache时间，在ehcache-shiro.xml中配置），超过这个时间间隔再刷新页面，该方法会被执行
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {

    	logger.info("##################执行Shiro权限认证##################");
        //获取当前登录输入的用户名，等价于
        String userName = (String)super.getAvailablePrincipal(principals); 
    	logger.info("##################开始查询用户【"+userName+"】的权限##################");

        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();

        /*List<Syspermission> permissionList = permissionMapper.getPermissionsByUser(userName);
        for(Syspermission permission:permissionList){
        	info.addStringPermission(permission.getPermission());
        	logger.info("##################权限【"+permission.getPermission()+"】##################");
        }*/
        List<Resource> resourceList = resourceMapper.getResourceByAccount(userName);
        for(Resource resource:resourceList){
        	info.addStringPermission(resource.getPermisCode());
        	logger.info("##################权限【"+resource.getPermisCode()+"】##################");
        }
        return info;
    }
    
/*    protected boolean onLoginSuccess(ServletRequest request,ServletResponse response,AuthenticationToken token,Subject subject){
    	//WebUtils.issueRedirect(request, response, getSuccessUrl());
    	return false;
    }*/

}
